#include <iostream>
#include <map>
#include <mutex>
#include <thread>
#include <vector>

#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>

#include "tcp_server.h"

// 使用 std::map 来存储已连接的客户端
// 使用 std::mutex 来保护 map 的访问
using ClientMap = std::map<int, TCPClient*>;
std::mutex g_client_mutex;
ClientMap g_clients;

void ClientManager::addClient(int fd, TCPClient *client)
{
    std::lock_guard<std::mutex> lock(g_client_mutex);
    printf("addClient: %s(%d)\n", client->name.c_str(), fd);
    g_clients[fd] = client;
}

void ClientManager::removeClient(int fd)
{
    std::lock_guard<std::mutex> lock(g_client_mutex);
    if (g_clients.find(fd) != g_clients.end())
    {
        printf("removeClient: %s(%d)\n", g_clients[fd]->name.c_str(), fd);
        shutdown(fd, SHUT_RDWR);
        close(fd);
        delete g_clients[fd];
        g_clients.erase(fd);
    }
}

void ClientManager::broadcast(const std::string &message)
{
    std::lock_guard<std::mutex> lock(g_client_mutex);
    for (auto &[fd, client] : g_clients)
    {
        if (client->authed)
        {
            send(fd, message.data(), message.size(), 0);
        }
    }
}

bool ClientManager::authClient(int fd)
{
    std::lock_guard<std::mutex> lock(g_client_mutex);
    if (g_clients.find(fd) != g_clients.end())
    {
        g_clients[fd]->authed = true;
    }
}

ClientManager g_client_manager;


#define BUFFER_LEN (1024 * 1024)
static char buffer[BUFFER_LEN];
#define KDELIMITER_LEN 13
static char kDelimiter[] = "$$panxuesen$$";
static int buffer_index = 0;

extern void processPacket(int fd, void* buffer, int len);

static void dealData(int fd, char data)
{
    if (buffer_index < BUFFER_LEN - 1)
    {
        buffer[buffer_index] = data;
        buffer_index++;
        if (buffer_index >= KDELIMITER_LEN)
        {
            if (strncmp(buffer + buffer_index - KDELIMITER_LEN, kDelimiter, KDELIMITER_LEN) == 0)
            {
                processPacket(fd, buffer, buffer_index - KDELIMITER_LEN);
                buffer_index = 0;
            }
        }
    }
    else
    {
        buffer_index = 0;
    }
}

void handleClient(int fd)
{
    char c[1024] = {0};
    while (true)
    {
        int bytes_received = recv(fd, buffer, sizeof(buffer), 0);
        if (bytes_received == 0 || bytes_received == -1)
        {
            g_client_manager.removeClient(fd);
            break;
        }

        for (size_t i = 0; i < bytes_received; i++)
        {
            dealData(fd, buffer[i]);
        }
        // std::string message(buffer, bytes_received);
        std::lock_guard<std::mutex> lock(g_client_mutex);
        if (g_clients.find(fd) != g_clients.end())
        {
            std::cout << "Received message from client: " << g_clients[fd]->name << " bytes_received:" << bytes_received << std::endl;
        }
        // g_client_manager.broadcast(message);
    }
}

static int server_fd = -1;
void tcp_broadcast(const std::string &message)
{
    g_client_manager.broadcast(message);
}

int main_tcp_server(int port)
{
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd == -1)
    {
        std::cerr << "Failed to create socket" << std::endl;
        return 1;
    }

    sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    // 设置服务器地址，这里设置为 localhost 的 12345 端口
    server_address.sin_addr.s_addr = INADDR_ANY;
    server_address.sin_port = htons(port);

    // 绑定套接字
    if (bind(server_fd, (sockaddr *)&server_address, sizeof(server_address)) == -1)
    {
        std::cerr << "Failed to bind socket" << std::endl;
        return 1;
    }

    // 监听套接字
    if (listen(server_fd, 10) == -1)
    {
        std::cerr << "Failed to listen on socket" << std::endl;
        return 1;
    }

    std::cout << "Listen:" << port << std::endl;

    std::vector<std::thread> threads;
    while (true)
    {
        sockaddr_in client_address;
        socklen_t client_address_size = sizeof(client_address);

        // 接受客户端连接
        int client_fd = accept(server_fd, (sockaddr *)&client_address, &client_address_size);
        if (client_fd == -1)
        {
            std::cerr << "Failed to accept client connection" << std::endl;
            break;
        }

        // 打印客户端 IP 地址
        char client_ip[INET_ADDRSTRLEN] = {0};
        inet_ntop(AF_INET, &client_address.sin_addr, client_ip, INET_ADDRSTRLEN);
        std::cout << "Accepted client connection from " << client_ip << std::endl;
        TCPClient *client = new TCPClient();
        client->ip = client_ip;
        client->name = std::string("Client:") + client_ip + ":" + std::to_string(client_address.sin_port);
        client->socketfd = client_fd;
        client->authed = false;
        g_client_manager.addClient(client_fd, client);

        // 为新连接的客户端创建一个新的线程
        threads.emplace_back(handleClient, client_fd);
    }

    return 0;
}

void main_tcp_server_close()
{
    if(server_fd != -1)
    {
        std::cerr << "close server_fd " << server_fd << std::endl;
        shutdown(server_fd, SHUT_RDWR);
        close(server_fd);
        server_fd = -1;
    }
}
